package com.cavy.platform.server.repository.impl;

import com.cavy.platform.server.CavyConfig;
import com.cavy.platform.server.domain.job.AbstractJobAction;
import com.cavy.platform.server.domain.job.Job;
import com.cavy.platform.server.domain.job.JobAction;
import com.cavy.platform.server.domain.job.RunningJob;
import com.cavy.platform.server.dto.JobSearchListDto;
import com.cavy.platform.server.repository.JobRepository;
import com.cavy.platform.server.util.FileUtils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author 唐旭
 * @Date 2018/7/25
 */
@Repository
public class JobRepositoryImpl implements JobRepository {
    private static final String JOB_FILE_NAME_TEMPLATE = "%s-%s-%s-%s.json";
    private static final String FILE_EXT = "json";
    @Autowired
    private CavyConfig config;

    @Override
    public void save(JobAction jobAction) {
        Job job = jobAction.getJob();
        File jobFile = getJobFile(job);
        save(jobAction, jobFile);
    }

    private File getJobFile(Job job) {
        return getJobFile(job.getWorkspaceName(), job.getProjectName(), job.getPipelineName(), job.getNumber());
    }

    private File getParentDir() {
        File dir = config.getJob().getDirFile();
        if (!dir.exists()) {
            boolean mkdirs = dir.mkdirs();
            if (!mkdirs) {
                throw new RuntimeException("创建文件夹:" + dir.getPath() + "失败");
            }
        }
        return dir;
    }

    @Override
    public JobAction load(String workspaceName, String projectName, String pipelineName, String number) {
        File jobFile = getJobFile(workspaceName, projectName, pipelineName, number);
        if (!jobFile.exists()) {
            throw new NullPointerException("未找到文件:" + jobFile.getPath());
        }

        return read(jobFile);
    }

    private File getJobFile(String workspaceName, String projectName, String pipelineName, String number) {
        File parentDir = getParentDir();
        String format = String.format(JOB_FILE_NAME_TEMPLATE, workspaceName, projectName, pipelineName, number);
        return new File(parentDir, format);
    }

    @Override
    public void delete(RunningJob job) {
        Job job1 = job.getJob();
        File jobFile = getJobFile(job1);
        FileUtils.delete(jobFile);
    }

    @Override
    public List<JobAction> find(JobSearchListDto dto) {
        String pre = String.format("%s-%s-%s", dto.getWorkSpace(), dto.getProject(), dto.getPipeline());
        File parentDir = getParentDir();
        File[] listFiles = parentDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String name1 = pathname.getName();
                String[] split = name1.split("-");
                if (split.length != 4) {
                    return false;
                }
                String fileExt = FileUtils.getFileExt(name1);
                if (!fileExt.equalsIgnoreCase(FILE_EXT)) {
                    return false;
                }
                if (!name1.startsWith(pre)) {
                    return false;
                }
                String name = dto.getName();
                if (!StringUtils.isEmpty(name)) {
                    return name1.contains(name);
                }

                return true;
            }
        });
        if (listFiles == null || listFiles.length == 0) {
            return Collections.emptyList();
        }
        List<JobAction> actions = new ArrayList<>(listFiles.length);
        for (File listFile : listFiles) {
            actions.add(read(listFile));
        }
        return actions;
    }

    @Override
    public List<JobAction> list() {
        File parentDir = getParentDir();
        File[] listFiles = parentDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String name1 = pathname.getName();
                String[] split = name1.split("-");
                if (split.length != 4) {
                    return false;
                }
                String fileExt = FileUtils.getFileExt(name1);
                if (!fileExt.equalsIgnoreCase(FILE_EXT)) {
                    return false;
                }
                return true;
            }
        });
        if (listFiles == null || listFiles.length == 0) {
            return Collections.emptyList();
        }
        List<JobAction> actions = new ArrayList<>(listFiles.length);
        for (File listFile : listFiles) {
            actions.add(read(listFile));
        }
        return actions;
    }

    private JobAction read(File jobFile) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        try {
            return mapper.readValue(jobFile, AbstractJobAction.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void save(JobAction job, File jobFile) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            mapper.writeValue(jobFile, job);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
